package cn.com.captureNetPacket.record;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import cn.com.captureNetPacket.util.WavFileUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Data
public class WavFileInfo {
	// Wav文件描述头
	private static final int HEAD_LENGTH = 12;

    private static final int FORMAT_LENGTH = 24;
    byte[] head=null;
    
    // Wav文件描述头 一共12字节,数组 0-11，一共12字节
    
    // 以'RIFF'作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 =Size.然后是Type字段,为'WAVE',表示是wav文件.   
    // head_chunkID : 固定4个英文字符  'R','I','F','F' 十六进制表示：52 49 46 46 。  4 字节  （0,4] 大端
    // head_chunkSize :文件大小-8就是这四个字节的值，表示这个标识之后的大小。也就是文件标识的8个字节去掉后的wav文件的数据字节数。4 字节，(4,8] 。十六进制反过来可转为10进制的数字。
    // head_formatType  :文件格式类型， wav文件 固定四个字符 WAVE  'W','A','V','E'  .4字节，(8,12] 。十六进制表示：57 41 56 45   
    byte[] headRiff=null;
	
    
    // format 文件格式区描述信息, 12-35，一共24字节
    // format_chunkID：固定4个英文字符  'F','M','T',' ' FIFF 4 字节  （12,16]  十六进制表示： 66 6d 74 20   4字节(12,16]   大端
    // format_chunkSize：表示该区块数据的长度（不包含ID和Size的长度）.一般情况下Size为16,此时最后附加信息没有;如果为18则最后多了2个字节的附加信息.主要由一些软件制成的wav格式.  4字节(16,20]
    
    // format_chunkSize   <!-- 这之间的长度
    // format_audioFormat  0x0001 WAVE_FORMAT_PCM 0x0003 WAVE_FORMAT_IEEE_FLOAT ，0x0006 WAVE_FORMAT_ALAM,0x0007 WAVE_FORMAT_MULAW，0xFFFE WAVE_FORMAT_EXTENSIBLE,等常用，2字节。 2字节 (20,22] 
    // format_channel 通道数. 单声道还是双声道。表示音频数据的声道数，1：单声道，2：双声道.2字节，(22,24]
    // format_sampleRate 表示音频数据的采样率 .  4字节，(24,28]
    // format_byteRate 每秒数据字节数 = SampleRate * NumChannels * BitsPerSample / 8. 4 字节，(28,32]
    // format_blockAlign 每个采样所需的字节数 = NumChannels * BitsPerSample / 8   2字节，(32,34]
    // format_bitsPerSample 每个采样存储的bit数，8：8bit，16：16bit，32：32bit    2字节 , (34,36]
    // 有附加信息时，这里增加2字节后面还增加了fact的附加信息的描述。后面fact描述14个字节。  2字节  (36,38]
    //  -->
    
    //  format_chunkSize :如果为18时出现下面三个。头信息总字节由44变为56
    // format_fact :固定4个英文字符  'F','A','C','T' FACT  十六进制表示： 66 61 63 74  4字节(38,42]   大端
    // fact_dataSize : 附加信息大小。 4字节。  (42,46]
    // fact_data : 附加信息数据 . 4字节。 (46,50]
    
    byte[] headFormat =null;
    
    // data s数据区域描述信息。 一共8字节
    // data_chunk_id  固定4个英文字符  'D','A','T','A' DATA  十六进制表示： 64 61 74 61   4 字节  （50,54]   大端      无fact时   （36,40]
    // data_size  4字节。数据大小。 4字节。 (54,58]    无fact时   （40,44]
    byte[] headData =null;
    
    
    private int head_chunkSize;
    
    // 16还是18 。判断是否有fact数据，初始化 headFormat 4字节
    private int format_chunkSize;
    // 1 pcm ,6 alaw,7 mulaw
    private short format_audioFormat;
    
    
    //通道数
    private short format_channel=1;
    private int   format_sampleRate;
    private int   format_byteRate;
    private short   format_blockAlign;
    private short   format_bitsPerSample;
    /**
     * 18字节时的末尾两个字节的信息
     */
    private short   format_factEnd;
    /**
     *音频数据块的实际大小
     */
    private int   data_size;
    /**
     *附加信息的大小
     */
    private int   fact_dataSize;
    /**
     * 附加信息数据
     */
    private byte[]   fact_data;
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 获取播放时长 <p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 下午9:20:52
    	* @return 返回毫秒
     */
    public long getDurationOfPlay() {
    	return data_size*1000/format_byteRate;
    }
    
    //文件大小
     private int fileSize;
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description:  16还是18 。判断是否有fact数据，初始化 headFormat 4字节<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:23:51
     	* @return
      */
     public int getFormat_chunkSize() {
    	 if(fact_data==null) {
    		 return 16;
    	 }
    	 else { 
    		 fact_dataSize=fact_data.length;
    		 try {
    			 if(headFormat!=null)
				log.info("headFormat.format_fact----------------->factID:{},fact_dataSize:{},fact_data:{}",new String(headFormat, 26, 4, "ISO_8859_1"),
						fact_dataSize,ByteBuffer.wrap(WavFileUtil.copyOfRange(fact_data, 0, 4)).order(ByteOrder.LITTLE_ENDIAN).getInt());
			} catch (UnsupportedEncodingException e) {
				log.error("getData_size",e);
			}
    		 return 18;
    	 }
     
     }
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description:  1 pcm ,6 alaw,7 mulaw<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:25:36
     	* @return
      */
     public short getFormat_audioFormat() {
    	 if(headFormat==null) {
    		 return format_audioFormat;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 8, 10))
                 .order(ByteOrder.LITTLE_ENDIAN).getShort();
     }
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 通道数. 单声道还是双声道。表示音频数据的声道数，1：单声道，2：双声道<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:26:29
     	* @return
      */
     public short getFormat_channel() {
    	 if(headFormat==null) {
    		 return format_channel;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 10, 12))
    			 .order(ByteOrder.LITTLE_ENDIAN).getShort();
     }
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 表示音频数据的采样率 .<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:26:52
     	* @return
      */
     public int getFormat_sampleRate() {
    	 if(headFormat==null) {
    		 return format_sampleRate;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 12, 16))
    			 .order(ByteOrder.LITTLE_ENDIAN).getInt();
     }
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 每秒数据字节数<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:27:00
     	* @return
      */
     public int getFormat_byteRate() {
    	 if(headFormat==null) {
    		 return format_byteRate;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 16, 20))
    			 .order(ByteOrder.LITTLE_ENDIAN).getInt();
     }
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 每个采样所需的字节数<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:27:41
     	* @return
      */
     public short getFormat_blockAlign() {
    	 if(headFormat==null) {
    		 return format_blockAlign;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 20, 22))
    			 .order(ByteOrder.LITTLE_ENDIAN).getShort();
     }
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 每个采样存储的bit数，8：8bit，16：16bit，32：32bit<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:28:45
     	* @return
      */
     public short getFormat_bitsPerSample() {
    	 if(headFormat==null) {
    		 return format_bitsPerSample;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 22, 24))
    			 .order(ByteOrder.LITTLE_ENDIAN).getShort();
     }
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: format 字节的时候获取,18字节时的末尾两个字节的信息<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:30:23
     	* @return
      */
     public short getFormat_factEnd() {
    	 if(headFormat==null || headFormat.length<25) {
    		 return format_factEnd;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headFormat, 24, 26))
    			 .order(ByteOrder.LITTLE_ENDIAN).getShort();
     }
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 真实数据的大小<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:31:27
     	* @return
      */
     public int getData_size() {
    	 if(headData==null ) {
    		 return data_size;
    	 }
    	 return ByteBuffer.wrap(WavFileUtil.copyOfRange(headData, 4, 8))
    			 .order(ByteOrder.LITTLE_ENDIAN).getInt();
     } 
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 文件实际大小<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:32:06
     	* @return
      */
     
     public int getFileSize() {
    	 return head_chunkSize+8;
     } 
    
     	/**
     	 * 
     		* <strong>Title: <strong>
     		* <p>Description: 普通的不带附加信息的WAVE文件<p>
     		* <p>Company: </p> 
     		*<strong>Copyright:</strong> Copyright (c) 2019
     		* @version: 1.0
     		* @author  ASUS:augustWei
     		* @date  2020 下午6:04:27
     		* @param format_audioFormat  1 PCM,3,6 Alaw,7 Mulaw
     		* @param format_channel  声道数
     		* @param format_sampleRate 音频数据的采样率 8000,等
     		* @param format_bitsPerSample  每个采样存储的bit数，8：8bit  相当于 一个采样占2个byte，需要一个字节存储。，   16：16bit 相当于 一个采样占 2 个byte，需要2个字节存储。32：32bit  需要4个字节存储。
     		* @param data_size 数据的大小
     	 */
     public   WavFileInfo(short format_audioFormat,short format_channel,int format_sampleRate,short format_bitsPerSample,int data_size) {
    	 this.format_audioFormat=format_audioFormat;
    	 this.format_chunkSize=16;
    	 this.format_channel=format_channel;
    	 this.format_sampleRate=format_sampleRate;
    	 this.format_bitsPerSample=format_bitsPerSample;
    	 this.data_size=data_size;
    	 // 根据初始化信息计算各个属性
    	 this.head_chunkSize=data_size+44-8;
    	 this.format_byteRate=format_channel*format_sampleRate*format_bitsPerSample/8;
    	 this.format_blockAlign=(short) (format_channel*format_bitsPerSample/8);
     }
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: <p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午6:04:36
     	* @param format_audioFormat  1 PCM,3,6 Alaw,7 Mulaw
     	* @param format_channel  声道数
     	* @param format_sampleRate 音频数据的采样率 8000,等
     	* @param format_bitsPerSample  每个采样存储的bit数，8：8bit  相当于 一个采样占2个byte，需要一个字节存储。，   16：16bit 相当于 一个采样占 2 个byte，需要2个字节存储。32：32bit  需要4个字节存储。
     	* @param data_size 数据的大小
     	* @param format_factEnd 自定义添加附加信息时补的2位。short类型或2字符
     	* @param fact_data 附加信息的数据。4个byte
      */
     public   WavFileInfo(short format_audioFormat,short format_channel,int format_sampleRate,short format_bitsPerSample,int data_size,short format_factEnd,byte[] fact_data) {
    	 this.format_audioFormat=format_audioFormat;
    	 this.format_chunkSize=18;
    	 this.format_channel=format_channel;
    	 this.format_sampleRate=format_sampleRate;
    	 this.format_bitsPerSample=format_bitsPerSample;
    	 this.data_size=data_size;
    	 this.format_factEnd=format_factEnd;
    	 try {
    	 if(fact_data!=null)
    		 this.fact_data=fact_data;
		else
				this.fact_data= ByteBuffer.allocate(4).put("fact".getBytes("ISO_8859_1")).array();
			} catch (UnsupportedEncodingException e) {
				 log.error("fact_data error",e);
			}
    	 
    	// 根据初始化信息计算各个属性
    	 this.head_chunkSize=data_size+58-8;
    	 this.format_byteRate=format_channel*format_sampleRate*format_bitsPerSample/8;
    	 this.format_blockAlign=(short) (format_channel*format_bitsPerSample/8);
     }
     
     /**
      * 
     	* <strong>Title: <strong>
     	* <p>Description: 根据头数组，重新计算头信息，数据大小和采样率<p>
     	* <p>Company: </p> 
     	*<strong>Copyright:</strong> Copyright (c) 2019
     	* @version: 1.0
     	* @author  ASUS:augustWei
     	* @date  2020 下午9:32:23
      */
     public void reInitValue() {
    	 if(fact_data!=null)
    	 {
    		 this.head_chunkSize=data_size+58-8;
    	 }
    	 else {
    		 this.head_chunkSize=data_size+44-8;
    	}
    	 this.format_byteRate=format_channel*format_sampleRate*format_bitsPerSample/8;
    	 this.format_blockAlign=(short) (format_channel*format_bitsPerSample/8);
     }
     
	public WavFileInfo() {
	}
     
     
    }
